package com.ng.desktop.view.alimento;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.apache.commons.lang.StringUtils;

import com.ng.desktop.model.Alimento;
import com.ng.desktop.model.Categoria;
import com.ng.desktop.model.UnidadMedida;
import com.ng.desktop.persistence.AlimentoPersistence;
import com.ng.desktop.services.NGFactoryBean;
import com.ng.desktop.services.THListingService;
import com.ng.framework.persistence.NGListingBean;
import com.ng.framework.util.NGUtil;
import com.ng.framework.view.desktop.NGEditDialog;
import com.ng.framework.view.desktop.NGCombo;

public class AlimentoEditDialog extends NGEditDialog<Alimento, AlimentoPersistence> {

	private static final long serialVersionUID = 2134402237990250514L;

	private static final NumberFormat DECIMAL_FORMAT = new DecimalFormat("0.00");

	private THListingService thListingService;

	private JTextField textFieldId;
	private JTextField textFieldNombre;
	private NGCombo comboCategoria;
	private JTextField textFieldCantidad;
	private NGCombo comboUnidadMedida;

	public AlimentoEditDialog(Frame owner, AlimentoPersistence persistence) {
		this(owner, persistence, null);
	}

	public AlimentoEditDialog(Frame owner, AlimentoPersistence persistence, Alimento instance) {
		super(owner, persistence, instance);

		this.setTitle("Gestión de Alimento");
		this.setSize(new Dimension(400, 300));
	}

	@Override
	protected JPanel createDetailPanel() {
		this.textFieldId = new JTextField(5);
		textFieldId.setEditable(false);
		textFieldId.setFocusable(false);
		textFieldId.setHorizontalAlignment(JTextField.RIGHT);
		this.textFieldNombre = new JTextField();
		this.comboCategoria = new NGCombo();
		comboCategoria.addNGItems(getListingService().getList(THListingService.CATEGORIAS, null, null));
		this.textFieldCantidad = new JTextField(5);
		textFieldCantidad.setHorizontalAlignment(JTextField.RIGHT);
		this.comboUnidadMedida = new NGCombo();
		comboUnidadMedida.addNGItems(this.getListingService().getList(THListingService.UNIDADES_MEDIDA, null, null));

		JPanel detailPanel = new JPanel(new GridBagLayout());

		detailPanel.add(new JLabel("Id:"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(textFieldId, new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
				new Insets(0, 0, 5, 0), 0, 0));
		detailPanel.add(new JLabel("Nombre:"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(textFieldNombre, new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		detailPanel.add(new JLabel("Categoría:"), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(comboCategoria, new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		detailPanel.add(new JLabel("Unidad (Porción):"), new GridBagConstraints(0, 3, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(comboUnidadMedida, new GridBagConstraints(1, 3, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		detailPanel.add(new JLabel("Cantidad (Porción):"), new GridBagConstraints(0, 4, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
		detailPanel.add(textFieldCantidad, new GridBagConstraints(1, 4, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));

		return detailPanel;
	}

	private THListingService getListingService() {
		if (thListingService == null) {
			thListingService = (THListingService) NGFactoryBean.getInstance().getBean("thListingService");
		}
		return thListingService;
	}

	@Override
	protected void populateDetailPanel(Alimento instance) {
		textFieldId.setText(String.valueOf(instance.getId()));
		textFieldNombre.setText(instance.getNombre());
		comboCategoria.setSelectedNGItem(instance.getCategoria());
		comboUnidadMedida.setSelectedNGItem(instance.getUnidadMedida());
		textFieldCantidad.setText(instance.getCantidadFraccion());
	}

	@Override
	protected boolean validateInput() {
		boolean valid = true;

		if (StringUtils.isEmpty(textFieldNombre.getText())) {
			JOptionPane.showMessageDialog(this, "El campo 'Nombre' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			textFieldNombre.requestFocus();

			valid = false;
		} else if (comboCategoria.getSelectedNGItem() == null) {
			JOptionPane.showMessageDialog(this, "El campo 'Categoría' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			comboCategoria.requestFocus();

			valid = false;
		} else if (comboUnidadMedida.getSelectedNGItem() == null) {
			JOptionPane
					.showMessageDialog(this, "El campo 'Unidad (Porción)' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			comboUnidadMedida.requestFocus();

			valid = false;
		} else if (StringUtils.isEmpty(textFieldCantidad.getText())) {
			JOptionPane.showMessageDialog(this, "El campo 'Cantidad (Porción)' es obligatorio.", "Error",
					JOptionPane.ERROR_MESSAGE);
			textFieldCantidad.requestFocus();

			valid = false;
		} else if (!validateFraction(textFieldCantidad.getText())) {
			JOptionPane.showMessageDialog(this, "El contenido del campo 'Cantidad (Porción)' es inválido.", "Error",
					JOptionPane.ERROR_MESSAGE);
			textFieldCantidad.requestFocus();

			valid = false;
		}

		return valid;
	}

	private boolean validateFraction(final String fraction) {
		boolean valid = true;

		try {
			if (!validateDouble(fraction)) {
				NGUtil.fractionToDouble(fraction);
			}

		} catch (Exception e) {
			valid = false;
		}
		return valid;

	}

	private boolean validateDouble(final String s) {
		boolean valid = true;

		try {
			Double.parseDouble(s);
		} catch (NumberFormatException e) {
			valid = false;
		}

		return valid;
	}

	@Override
	protected Alimento createNewInstance() {
		return new Alimento();
	}

	@Override
	protected void populateInstance(Alimento instance) {
		String cantidadFraccion;
		Double cantidad;
		try {
			cantidad = Double.parseDouble(textFieldCantidad.getText());
			cantidadFraccion = NGUtil.doubleToFraction(cantidad, true);
		} catch (NumberFormatException e) {
			cantidadFraccion = textFieldCantidad.getText();
			cantidad = NGUtil.fractionToDouble(cantidadFraccion);
		}

		instance.setCantidad(cantidad);
		instance.setCantidadFraccion(cantidadFraccion);
		instance.setCategoria(this.getListingService().getHydratedBean((NGListingBean) comboCategoria.getSelectedNGItem(),
				Categoria.class));
		instance.setNombre(textFieldNombre.getText());
		instance.setUnidadMedida(this.getListingService().getHydratedBean((NGListingBean) comboUnidadMedida.getSelectedNGItem(),
				UnidadMedida.class));
	}
}
